#include "../include/media_defs.h"
#include <pthread.h>

extern pthread_mutex_t lock;
float volume = 0.5;
int paused = 0;
int current_song = 0;
int status = 0;
int playlist_size;
const char *playlist[] = {
    "/home/ubuntu/git/in-vehicle/resources/泠鸢yousa - 勾指起誓.mp3",
    "/home/ubuntu/git/in-vehicle/resources/十年.mp3",
    "/home/ubuntu/git/in-vehicle/resources/搀扶.mp3"
};

void check_mpg123_error(int err, mpg123_handle *mh) {
    if (err != MPG123_OK) {
        fprintf(stderr, "mpg123错误: %s\n", mpg123_strerror(mh));
        exit(1);
    }
}

int kbhit(void) {
    struct termios oldt, newt;
    int ch, oldf;
    tcgetattr(STDIN_FILENO, &oldt);
    newt = oldt;
    newt.c_lflag &= ~(ICANON | ECHO);
    tcsetattr(STDIN_FILENO, TCSANOW, &newt);
    oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
    fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);
    ch = getchar();
    tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
    fcntl(STDIN_FILENO, F_SETFL, oldf);
    if (ch != EOF) {
        ungetc(ch, stdin);
        return 1;
    }
    return 0;
}

ao_device *play_song(mpg123_handle *mh, ao_device *device, const char *mp3File, float *volume, int *paused, int *status) {
    *status = 0;

    if (access(mp3File, F_OK) != 0) {
        return device;
    }

    int err = mpg123_open(mh, mp3File);
    if (err != MPG123_OK) {
        return device;
    }

    long rate;
    int channels, encoding;
    err = mpg123_getformat(mh, &rate, &channels, &encoding);
    check_mpg123_error(err, mh);

    ao_sample_format format = {0};
    format.bits = mpg123_encsize(encoding) * 8;
    format.rate = rate;
    format.channels = channels;
    format.byte_format = AO_FMT_NATIVE;
    format.matrix = NULL;

    if (device) {
        ao_close(device);
    }
    device = ao_open_live(ao_default_driver_id(), &format, NULL);
    if (!device) {
        mpg123_close(mh);
        return NULL;
    }

    mpg123_volume(mh, *volume);

    unsigned char *buffer;
    size_t buffer_size = mpg123_outblock(mh);
    buffer = malloc(buffer_size);
    size_t done;

    while (mpg123_read(mh, buffer, buffer_size, &done) == MPG123_OK) {
        pthread_mutex_lock(&lock);
        if (!*paused) {
            ao_play(device, (char *)buffer, done);
        }
        if (*status == 2) {
            break;
        }
        pthread_mutex_unlock(&lock);
        if (*paused) {
            usleep(100000);
        }
    }

    free(buffer);
    mpg123_close(mh);
    return device;
}

void background_play(mpg123_handle *mh, ao_device **device) {
    playlist_size = sizeof(playlist) / sizeof(playlist[0]);

    mpg123_init();
    ao_initialize();

    int err;
    mh = mpg123_new(NULL, &err);
    check_mpg123_error(err, mh);

    *device = NULL;

    while (run_b) {
        pthread_mutex_lock(&lock);
        if (current_song < 0) current_song = playlist_size - 1;
        if (current_song >= playlist_size) current_song = 0;
        status = 0;
        pthread_mutex_unlock(&lock);

        *device = play_song(mh, *device, playlist[current_song], &volume, &paused, &status);

        pthread_mutex_lock(&lock);
        if (status == 2) {
            break;
        } else if (status == 1) {
            current_song++;
        } else if (status == -1) {
            current_song--;
        } else {
            current_song++;
        }
        pthread_mutex_unlock(&lock);

        usleep(100000);
    }

    if (*device) ao_close(*device);
    mpg123_delete(mh);
    mpg123_exit();
    ao_shutdown();
}

int MultimediaControl_Main(void) {
    printf("控制: 'p' 暂停/继续, '+' 增加音量, '-' 减少音量, 'n' 下一首, 'b' 上一首, 'q' 退出\n");
    printf("正在播放: %s\n", playlist[current_song]);

    while (1) {
        if (kbhit()) {
            char c = getchar();
            pthread_mutex_lock(&lock);
            if (c == 'p') {
                paused = !paused;
                printf(paused ? "已暂停\n" : "继续播放\n");
            } else if (c == '+') {
                volume = volume + 0.1 > 1.0 ? 1.0 : volume + 0.1;
                printf("音量: %.1f\n", volume);
            } else if (c == '-') {
                volume = volume - 0.1 < 0.0 ? 0.0 : volume - 0.1;
                printf("音量: %.1f\n", volume);
            } else if (c == 'n') {
                status = 1;
                printf("切换到下一首\n");
            } else if (c == 'b') {
                status = -1;
                printf("切换到上一首\n");
            } else if (c == 'q') {
                status = 2;
                pthread_mutex_unlock(&lock);
                printf("退出多媒体控制，前台模式结束（后台继续播放）\n");
                return 0;
            }
            pthread_mutex_unlock(&lock);
        }
        usleep(100000);
    }
    return 0;
}